"""
学术研究自动化RESTful API

提供完整的REST API接口，包括：
- 用户认证和授权
- 项目管理
- 数据分析
- 协作功能
- 系统管理
- API文档自动生成
- API版本管理
"""
import os
import json
from datetime import datetime, timedelta
from functools import wraps
from typing import Dict, Any, Optional, List

from flask import Flask, request, jsonify, g
from flask_cors import CORS
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
import jwt

# 导入我们的服务
from research_automation.services.security_service import SecurityService, UserRole, Permission
from research_automation.services.data_security_service import DataSecurityService, DataClassification
from research_automation.services.input_validation_service import InputValidationService, ValidationLevel


class ResearchAutomationAPI:
    """学术研究自动化RESTful API"""
    
    def __init__(self):
        self.app = Flask(__name__)
        
        # 配置
        self.app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'api-secret-key-change-in-production')
        self.app.config['API_VERSION'] = 'v1'
        self.app.config['API_TITLE'] = '学术研究自动化API'
        self.app.config['API_DESCRIPTION'] = '提供学术研究自动化功能的RESTful API'
        
        # 启用CORS
        CORS(self.app, resources={
            r"/api/*": {
                "origins": ["http://localhost:3000", "http://127.0.0.1:5000"],
                "methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
                "allow_headers": ["Content-Type", "Authorization"]
            }
        })
        
        # 速率限制
        self.limiter = Limiter(
            app=self.app,
            key_func=get_remote_address,
            default_limits=["1000 per hour", "100 per minute"]
        )
        
        # 初始化服务
        self.security_service = SecurityService(secret_key=self.app.config['SECRET_KEY'])
        self.data_security_service = DataSecurityService()
        self.validation_service = InputValidationService(ValidationLevel.STANDARD)
        
        # 注册路由
        self._register_routes()
        
        # 注册错误处理器
        self._register_error_handlers()
        
        # 注册中间件
        self._register_middleware()
    
    def _register_middleware(self):
        """注册中间件"""
        
        @self.app.before_request
        def before_request():
            """请求前处理"""
            # 记录请求信息
            g.start_time = datetime.now()
            g.request_id = f"req_{int(datetime.now().timestamp() * 1000)}"
            
            # 输入验证
            if request.method in ['POST', 'PUT', 'PATCH']:
                if request.is_json and request.get_json():
                    data = request.get_json()
                    for key, value in data.items():
                        if isinstance(value, str):
                            validation_result = self.validation_service.validate_input(
                                value,
                                context=f"api_{key}",
                                source_ip=request.remote_addr
                            )
                            
                            if validation_result.result.value == 'dangerous':
                                return jsonify({
                                    'error': 'Invalid input detected',
                                    'message': '输入包含危险内容',
                                    'request_id': g.request_id
                                }), 400
        
        @self.app.after_request
        def after_request(response):
            """请求后处理"""
            # 添加响应头
            response.headers['X-Request-ID'] = g.request_id
            response.headers['X-API-Version'] = self.app.config['API_VERSION']
            response.headers['X-Response-Time'] = str(
                (datetime.now() - g.start_time).total_seconds() * 1000
            ) + 'ms'
            
            return response
    
    def _register_routes(self):
        """注册API路由"""
        
        # API信息
        @self.app.route('/api', methods=['GET'])
        def api_info():
            """API信息"""
            return jsonify({
                'name': self.app.config['API_TITLE'],
                'description': self.app.config['API_DESCRIPTION'],
                'version': self.app.config['API_VERSION'],
                'timestamp': datetime.now().isoformat(),
                'endpoints': {
                    'auth': '/api/v1/auth',
                    'users': '/api/v1/users',
                    'projects': '/api/v1/projects',
                    'analysis': '/api/v1/analysis',
                    'collaboration': '/api/v1/collaboration',
                    'admin': '/api/v1/admin',
                    'docs': '/api/v1/docs'
                }
            })
        
        # 健康检查
        @self.app.route('/api/health', methods=['GET'])
        def health_check():
            """健康检查"""
            return jsonify({
                'status': 'healthy',
                'timestamp': datetime.now().isoformat(),
                'version': self.app.config['API_VERSION'],
                'services': {
                    'security': 'operational',
                    'data_security': 'operational',
                    'validation': 'operational'
                }
            })
        
        # 认证相关API
        @self.app.route('/api/v1/auth/login', methods=['POST'])
        @self.limiter.limit("10 per minute")
        def auth_login():
            """用户登录"""
            data = request.get_json()
            
            if not data or not data.get('username') or not data.get('password'):
                return jsonify({
                    'error': 'Missing credentials',
                    'message': '用户名和密码不能为空'
                }), 400
            
            # 用户认证
            auth_result = self.security_service.authenticate_user(
                data['username'],
                data['password'],
                request.remote_addr
            )
            
            if auth_result['success']:
                return jsonify({
                    'success': True,
                    'token': auth_result['token'],
                    'user': auth_result['user'],
                    'expires_in': 86400  # 24小时
                })
            else:
                return jsonify({
                    'error': 'Authentication failed',
                    'message': auth_result['error']
                }), 401
        
        @self.app.route('/api/v1/auth/register', methods=['POST'])
        @self.limiter.limit("5 per minute")
        def auth_register():
            """用户注册"""
            data = request.get_json()
            
            required_fields = ['username', 'email', 'password']
            for field in required_fields:
                if not data or not data.get(field):
                    return jsonify({
                        'error': 'Missing required field',
                        'message': f'缺少必填字段: {field}'
                    }), 400
            
            # 用户注册
            try:
                role = UserRole(data.get('role', 'student'))
            except ValueError:
                role = UserRole.STUDENT
            
            register_result = self.security_service.register_user(
                data['username'],
                data['email'],
                data['password'],
                role
            )
            
            if register_result['success']:
                return jsonify({
                    'success': True,
                    'user_id': register_result['user_id'],
                    'message': '注册成功'
                }), 201
            else:
                return jsonify({
                    'error': 'Registration failed',
                    'message': register_result['error']
                }), 400
        
        @self.app.route('/api/v1/auth/logout', methods=['POST'])
        @self.require_auth
        def auth_logout():
            """用户登出"""
            # 这里可以实现令牌黑名单等逻辑
            return jsonify({
                'success': True,
                'message': '登出成功'
            })
        
        @self.app.route('/api/v1/auth/refresh', methods=['POST'])
        @self.require_auth
        def auth_refresh():
            """刷新令牌"""
            user = g.current_user
            new_token = self.security_service._generate_jwt_token(user)
            
            return jsonify({
                'success': True,
                'token': new_token,
                'expires_in': 86400
            })
        
        # 用户管理API
        @self.app.route('/api/v1/users/profile', methods=['GET'])
        @self.require_auth
        def get_user_profile():
            """获取用户资料"""
            user_info = self.security_service.get_user_info(g.current_user.user_id)
            
            if user_info:
                # 移除敏感信息
                safe_info = {
                    'user_id': user_info['user_id'],
                    'username': user_info['username'],
                    'email': user_info['email'],
                    'role': user_info['role'],
                    'created_at': user_info['created_at'],
                    'last_login': user_info['last_login']
                }
                return jsonify({
                    'success': True,
                    'user': safe_info
                })
            else:
                return jsonify({
                    'error': 'User not found',
                    'message': '用户不存在'
                }), 404
        
        @self.app.route('/api/v1/users/profile', methods=['PUT'])
        @self.require_auth
        def update_user_profile():
            """更新用户资料"""
            data = request.get_json()
            
            # 这里应该实现用户资料更新逻辑
            return jsonify({
                'success': True,
                'message': '资料更新成功'
            })
        
        @self.app.route('/api/v1/users', methods=['GET'])
        @self.require_auth
        @self.require_permission(Permission.MANAGE_USERS)
        def list_users():
            """获取用户列表"""
            page = request.args.get('page', 1, type=int)
            per_page = min(request.args.get('per_page', 20, type=int), 100)
            
            # 这里应该实现分页查询逻辑
            users = []
            for user_id, user in list(self.security_service.users.items())[:per_page]:
                users.append({
                    'user_id': user.user_id,
                    'username': user.username,
                    'email': user.email,
                    'role': user.role.value,
                    'is_active': user.is_active,
                    'created_at': user.created_at.isoformat()
                })
            
            return jsonify({
                'success': True,
                'users': users,
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total': len(self.security_service.users),
                    'pages': (len(self.security_service.users) + per_page - 1) // per_page
                }
            })
        
        # 项目管理API
        @self.app.route('/api/v1/projects', methods=['GET'])
        @self.require_auth
        def list_projects():
            """获取项目列表"""
            # 示例项目数据
            projects = [
                {
                    'id': 1,
                    'name': '人工智能在医疗诊断中的应用',
                    'description': '研究AI技术在医疗诊断领域的应用',
                    'status': 'active',
                    'progress': 65,
                    'created_at': '2024-01-15T10:00:00Z',
                    'updated_at': '2024-01-20T15:30:00Z',
                    'owner_id': g.current_user.user_id,
                    'collaborators': 3
                },
                {
                    'id': 2,
                    'name': '机器学习算法优化研究',
                    'description': '优化现有机器学习算法的性能',
                    'status': 'completed',
                    'progress': 100,
                    'created_at': '2023-11-20T09:00:00Z',
                    'updated_at': '2024-01-10T16:45:00Z',
                    'owner_id': g.current_user.user_id,
                    'collaborators': 2
                }
            ]
            
            return jsonify({
                'success': True,
                'projects': projects,
                'total': len(projects)
            })
        
        @self.app.route('/api/v1/projects', methods=['POST'])
        @self.require_auth
        @self.require_permission(Permission.CREATE_RESEARCH)
        def create_project():
            """创建新项目"""
            data = request.get_json()
            
            required_fields = ['name', 'description']
            for field in required_fields:
                if not data or not data.get(field):
                    return jsonify({
                        'error': 'Missing required field',
                        'message': f'缺少必填字段: {field}'
                    }), 400
            
            # 数据加密存储
            classification = DataClassification.CONFIDENTIAL if data.get('privacy_level') == 'confidential' else DataClassification.INTERNAL
            
            encrypt_result = self.data_security_service.encrypt_data(
                data=data,
                classification=classification,
                user_id=g.current_user.user_id
            )
            
            if encrypt_result['success']:
                project = {
                    'id': f"proj_{encrypt_result['data_id']}",
                    'name': data['name'],
                    'description': data['description'],
                    'status': 'active',
                    'progress': 0,
                    'created_at': datetime.now().isoformat(),
                    'owner_id': g.current_user.user_id
                }
                
                return jsonify({
                    'success': True,
                    'project': project,
                    'message': '项目创建成功'
                }), 201
            else:
                return jsonify({
                    'error': 'Project creation failed',
                    'message': '项目创建失败'
                }), 500
        
        @self.app.route('/api/v1/projects/<project_id>', methods=['GET'])
        @self.require_auth
        def get_project(project_id):
            """获取项目详情"""
            # 示例项目数据
            project = {
                'id': project_id,
                'name': '人工智能在医疗诊断中的应用',
                'description': '研究AI技术在医疗诊断领域的应用',
                'status': 'active',
                'progress': 65,
                'created_at': '2024-01-15T10:00:00Z',
                'updated_at': '2024-01-20T15:30:00Z',
                'owner_id': g.current_user.user_id,
                'collaborators': [
                    {'user_id': 'user_001', 'username': 'researcher1', 'role': 'collaborator'},
                    {'user_id': 'user_002', 'username': 'student1', 'role': 'assistant'}
                ],
                'tasks': [
                    {'id': 1, 'title': '文献调研', 'status': 'completed', 'progress': 100},
                    {'id': 2, 'title': '数据收集', 'status': 'in_progress', 'progress': 60},
                    {'id': 3, 'title': '模型训练', 'status': 'pending', 'progress': 0}
                ]
            }
            
            return jsonify({
                'success': True,
                'project': project
            })
        
        @self.app.route('/api/v1/projects/<project_id>', methods=['PUT'])
        @self.require_auth
        def update_project(project_id):
            """更新项目"""
            data = request.get_json()
            
            # 这里应该实现项目更新逻辑
            return jsonify({
                'success': True,
                'message': '项目更新成功'
            })
        
        @self.app.route('/api/v1/projects/<project_id>', methods=['DELETE'])
        @self.require_auth
        @self.require_permission(Permission.DELETE_RESEARCH)
        def delete_project(project_id):
            """删除项目"""
            # 这里应该实现项目删除逻辑
            return jsonify({
                'success': True,
                'message': '项目删除成功'
            })
        
        # 数据分析API
        @self.app.route('/api/v1/analysis', methods=['GET'])
        @self.require_auth
        def list_analyses():
            """获取分析列表"""
            analyses = [
                {
                    'id': 1,
                    'name': '用户行为分析',
                    'type': 'statistical',
                    'status': 'completed',
                    'created_at': '2024-01-20T10:00:00Z',
                    'project_id': 1
                },
                {
                    'id': 2,
                    'name': '实验数据可视化',
                    'type': 'visualization',
                    'status': 'in_progress',
                    'created_at': '2024-01-25T14:30:00Z',
                    'project_id': 1
                }
            ]
            
            return jsonify({
                'success': True,
                'analyses': analyses,
                'total': len(analyses)
            })
        
        @self.app.route('/api/v1/analysis', methods=['POST'])
        @self.require_auth
        def create_analysis():
            """创建新分析"""
            data = request.get_json()
            
            # 这里应该实现分析创建逻辑
            analysis = {
                'id': f"analysis_{int(datetime.now().timestamp())}",
                'name': data.get('name', '新分析'),
                'type': data.get('type', 'statistical'),
                'status': 'pending',
                'created_at': datetime.now().isoformat()
            }
            
            return jsonify({
                'success': True,
                'analysis': analysis,
                'message': '分析创建成功'
            }), 201
        
        # 协作管理API
        @self.app.route('/api/v1/collaboration/invitations', methods=['GET'])
        @self.require_auth
        def list_invitations():
            """获取协作邀请"""
            invitations = [
                {
                    'id': 1,
                    'project_id': 1,
                    'project_name': '跨学科研究项目',
                    'inviter': 'prof_smith',
                    'role': 'collaborator',
                    'status': 'pending',
                    'created_at': '2024-01-25T09:00:00Z'
                }
            ]
            
            return jsonify({
                'success': True,
                'invitations': invitations,
                'total': len(invitations)
            })
        
        @self.app.route('/api/v1/collaboration/invitations/<int:invitation_id>/accept', methods=['POST'])
        @self.require_auth
        def accept_invitation(invitation_id):
            """接受协作邀请"""
            return jsonify({
                'success': True,
                'message': '邀请已接受'
            })
        
        @self.app.route('/api/v1/collaboration/invitations/<int:invitation_id>/decline', methods=['POST'])
        @self.require_auth
        def decline_invitation(invitation_id):
            """拒绝协作邀请"""
            return jsonify({
                'success': True,
                'message': '邀请已拒绝'
            })
        
        # 系统管理API
        @self.app.route('/api/v1/admin/stats', methods=['GET'])
        @self.require_auth
        @self.require_permission(Permission.MANAGE_SYSTEM)
        def admin_stats():
            """获取系统统计"""
            security_stats = self.security_service.get_security_stats()
            validation_stats = self.validation_service.get_validation_statistics()
            
            return jsonify({
                'success': True,
                'stats': {
                    'security': security_stats,
                    'validation': validation_stats,
                    'system': {
                        'uptime': '24h 15m',
                        'memory_usage': '45%',
                        'cpu_usage': '12%',
                        'disk_usage': '68%'
                    }
                }
            })
        
        @self.app.route('/api/v1/admin/security/events', methods=['GET'])
        @self.require_auth
        @self.require_permission(Permission.VIEW_LOGS)
        def admin_security_events():
            """获取安全事件"""
            limit = min(request.args.get('limit', 50, type=int), 100)
            events = self.security_service.get_security_events(limit=limit)
            
            return jsonify({
                'success': True,
                'events': events,
                'total': len(events)
            })
        
        # API文档
        @self.app.route('/api/v1/docs', methods=['GET'])
        def api_docs():
            """API文档"""
            return jsonify({
                'openapi': '3.0.0',
                'info': {
                    'title': self.app.config['API_TITLE'],
                    'description': self.app.config['API_DESCRIPTION'],
                    'version': self.app.config['API_VERSION'],
                    'contact': {
                        'name': 'API Support',
                        'email': 'support@research-automation.com'
                    }
                },
                'servers': [
                    {
                        'url': '/api/v1',
                        'description': 'Production server'
                    }
                ],
                'paths': self._generate_api_docs()
            })
    
    def _register_error_handlers(self):
        """注册错误处理器"""
        
        @self.app.errorhandler(400)
        def bad_request(error):
            return jsonify({
                'error': 'Bad Request',
                'message': '请求参数错误',
                'status_code': 400,
                'request_id': getattr(g, 'request_id', None)
            }), 400
        
        @self.app.errorhandler(401)
        def unauthorized(error):
            return jsonify({
                'error': 'Unauthorized',
                'message': '未授权访问',
                'status_code': 401,
                'request_id': getattr(g, 'request_id', None)
            }), 401
        
        @self.app.errorhandler(403)
        def forbidden(error):
            return jsonify({
                'error': 'Forbidden',
                'message': '权限不足',
                'status_code': 403,
                'request_id': getattr(g, 'request_id', None)
            }), 403
        
        @self.app.errorhandler(404)
        def not_found(error):
            return jsonify({
                'error': 'Not Found',
                'message': '资源不存在',
                'status_code': 404,
                'request_id': getattr(g, 'request_id', None)
            }), 404
        
        @self.app.errorhandler(429)
        def rate_limit_exceeded(error):
            return jsonify({
                'error': 'Rate Limit Exceeded',
                'message': '请求频率超过限制',
                'status_code': 429,
                'request_id': getattr(g, 'request_id', None)
            }), 429
        
        @self.app.errorhandler(500)
        def internal_error(error):
            return jsonify({
                'error': 'Internal Server Error',
                'message': '服务器内部错误',
                'status_code': 500,
                'request_id': getattr(g, 'request_id', None)
            }), 500
    
    def require_auth(self, f):
        """认证装饰器"""
        @wraps(f)
        def decorated_function(*args, **kwargs):
            auth_header = request.headers.get('Authorization')
            
            if not auth_header or not auth_header.startswith('Bearer '):
                return jsonify({
                    'error': 'Missing or invalid authorization header',
                    'message': '缺少或无效的授权头'
                }), 401
            
            token = auth_header.split(' ')[1]
            token_result = self.security_service.verify_token(token)
            
            if not token_result['valid']:
                return jsonify({
                    'error': 'Invalid or expired token',
                    'message': token_result['error']
                }), 401
            
            # 获取用户信息
            user_id = token_result['user']['user_id']
            user = self.security_service.users.get(user_id)
            
            if not user or not user.is_active:
                return jsonify({
                    'error': 'User not found or inactive',
                    'message': '用户不存在或已被禁用'
                }), 401
            
            g.current_user = user
            return f(*args, **kwargs)
        
        return decorated_function
    
    def require_permission(self, permission: Permission):
        """权限检查装饰器"""
        def decorator(f):
            @wraps(f)
            def decorated_function(*args, **kwargs):
                if not hasattr(g, 'current_user'):
                    return jsonify({
                        'error': 'Authentication required',
                        'message': '需要认证'
                    }), 401
                
                if not self.security_service.check_permission(g.current_user.user_id, permission):
                    return jsonify({
                        'error': 'Insufficient permissions',
                        'message': '权限不足'
                    }), 403
                
                return f(*args, **kwargs)
            return decorated_function
        return decorator
    
    def _generate_api_docs(self) -> Dict[str, Any]:
        """生成API文档"""
        return {
            '/auth/login': {
                'post': {
                    'summary': '用户登录',
                    'tags': ['Authentication'],
                    'requestBody': {
                        'required': True,
                        'content': {
                            'application/json': {
                                'schema': {
                                    'type': 'object',
                                    'properties': {
                                        'username': {'type': 'string'},
                                        'password': {'type': 'string'}
                                    },
                                    'required': ['username', 'password']
                                }
                            }
                        }
                    },
                    'responses': {
                        '200': {
                            'description': '登录成功',
                            'content': {
                                'application/json': {
                                    'schema': {
                                        'type': 'object',
                                        'properties': {
                                            'success': {'type': 'boolean'},
                                            'token': {'type': 'string'},
                                            'user': {'type': 'object'}
                                        }
                                    }
                                }
                            }
                        },
                        '401': {'description': '认证失败'}
                    }
                }
            },
            '/projects': {
                'get': {
                    'summary': '获取项目列表',
                    'tags': ['Projects'],
                    'security': [{'bearerAuth': []}],
                    'responses': {
                        '200': {
                            'description': '项目列表',
                            'content': {
                                'application/json': {
                                    'schema': {
                                        'type': 'object',
                                        'properties': {
                                            'success': {'type': 'boolean'},
                                            'projects': {
                                                'type': 'array',
                                                'items': {'type': 'object'}
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                'post': {
                    'summary': '创建新项目',
                    'tags': ['Projects'],
                    'security': [{'bearerAuth': []}],
                    'requestBody': {
                        'required': True,
                        'content': {
                            'application/json': {
                                'schema': {
                                    'type': 'object',
                                    'properties': {
                                        'name': {'type': 'string'},
                                        'description': {'type': 'string'}
                                    },
                                    'required': ['name', 'description']
                                }
                            }
                        }
                    },
                    'responses': {
                        '201': {'description': '项目创建成功'},
                        '400': {'description': '请求参数错误'}
                    }
                }
            }
        }
    
    def run(self, host='127.0.0.1', port=8000, debug=False):
        """运行API服务"""
        self.app.run(host=host, port=port, debug=debug)


# 创建API实例
def create_api():
    """创建API应用"""
    return ResearchAutomationAPI()


if __name__ == '__main__':
    api = create_api()
    api.run(debug=True)